package com.ecoolex.ying.space.api.graphql;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.lang.NonNull;

import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberAuthority;
import com.ecoolex.framework.modularize.api.service.storage.FileSize;
import com.ecoolex.framework.modularize.api.service.storage.MimeType;
import com.ecoolex.framework.modularize.api.service.storage.MultipartUpload;
import com.ecoolex.framework.modularize.api.service.storage.MultipartUploadResult;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.modularize.api.service.storage.Upload;
import com.ecoolex.framework.modularize.api.service.storage.UploadLimit;
import com.ecoolex.framework.modularize.api.service.storage.UploadSource;
import com.ecoolex.framework.modularize.api.service.storage.VideoUpload;
import com.ecoolex.framework.modularize.api.service.storage.VideoUploadResult;
import com.ecoolex.framework.modularize.api.service.storage.process.EventListenerProcess;
import com.ecoolex.framework.modularize.api.service.storage.process.ImageProcess;
import com.ecoolex.framework.modularize.api.service.storage.process.SubmitJobProcess;
import com.ecoolex.framework.modularize.api.service.storage.process.VideoGifProcess;
import com.ecoolex.framework.modularize.api.service.storage.process.VideoImageProcess;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.ying.space.api.core.ApiConstant;


@GraphQL2Module(type = Type.User, description = "用户作品、灵感存储管理")
public class UserWorksStorageGraphql {

    @Autowired
    private StorageService storageService;

    /**
     * 图片
     */

    private static final UploadSource IMAGE_SOURCE = new UploadSource("UserWorksImages", "Images");

    private static final UploadLimit IMAGE_LIMIT
        = new UploadLimit(FileSize.MB.byteLength(10), MimeType.IMAGE.commons());

    /**
     * base64 上传图片
     * 
     * @param request
     * @param user
     * @return
     */
    @MutationField(field = "uploadUserWorksImages", description = { "上传灵感图片" })
    public StorageInfo uploadGoodsImages(@NonNull Upload request, ConsumerMemberAuthority user) {
        user.assertLogin();
        return storageService.upload(request, IMAGE_SOURCE, IMAGE_LIMIT, this::addImageProcess);
    }

    /**
     * 流上传图片
     * 
     * @param user
     * @return
     */
    @MutationField(field = "createUserWorksImagesUploadToken", description = { "创建灵感图片文件上传Token" })
    public String createUserWorksImagesUploadToken(ConsumerMemberAuthority user) {
        user.assertLogin();
        return storageService.createUploadToken(IMAGE_SOURCE, IMAGE_LIMIT);
    }

    @MutationField(field = "completeUserWorksImagesUploadByToken", description = { "根据token完成灵感图片文件上传" })
    public StorageInfo completeUserWorksImagesUpload(@NonNull String token, ConsumerMemberAuthority user) {
        user.assertLogin();
        StorageInfo storageInfo = storageService.getByToken(token, IMAGE_SOURCE);
        addImageProcess(storageInfo);
        return storageInfo;
    }

    /**
     * 分片上传图片
     * 
     * @param request
     * @param user
     * @return
     */
    @MutationField(field = "createUserWorksImagesMultipartUpload", description = "创建灵感图片分片上传")
    public MultipartUploadResult createUserWorksImagesMultipartUpload(@NonNull MultipartUpload request, ConsumerMemberAuthority user) {
        user.assertLogin();
        return storageService.createMultipartUpload(request, IMAGE_SOURCE, IMAGE_LIMIT);
    }

    @MutationField(field = "completeUserWorksImagesMultipartUpload", description = "完成灵感图片分片上传")
    public StorageInfo completeUserWorksImagesMultipartUpload(@NonNull String uploadId, ConsumerMemberAuthority user) {
        user.assertLogin();
        return storageService.completeMultipartUpload(uploadId, VIDEO_SOURCE, this::addImageProcess);
    }

    /**
     * 对图片进行处理
     * 
     * @param info
     */
    private void addImageProcess(StorageInfo info) {
        // 自适应宽高
        int height = (int) info.getAttributes().get("height");
        int width = (int) info.getAttributes().get("width");

        ImageProcess imageProcess = new ImageProcess();
        imageProcess.setSync(true);
        imageProcess.setKey("preview");
        imageProcess.setQuality(0.8F);
        if (height < width) {
            imageProcess.setZoomMode(ApiConstant.USER_WORKS_COVER_IMAGE_ZOOM_TRANSVERSE);
        } else {
            imageProcess.setZoomMode(ApiConstant.USER_WORKS_COVER_IMAGE_ZOOM_VERTICAL);
        }

        storageService.addProcess(info.getStorageId(), imageProcess);
    }

    private static final UploadSource VIDEO_SOURCE = new UploadSource("UserWorksVideo", "Video");

    private static final UploadLimit VIDEO_LIMIT = new UploadLimit(FileSize.MB.byteLength(200), MimeType.VIDEO.alls());

    @Value("${aliyun.vod.works.transcodeTemplateId}")
    private String transcodeTemplateGroupId;

    @Value("${aliyun.vod.works.gifVerticalityTemplateId}")
    private String gifVerticalityTemplateId;

    @Value("${aliyun.vod.works.gifHorizontalTemplateId}")
    private String gifHorizontalTemplateId;

    @Value("${aliyun.vod.works.snapshotTemplateId}")
    private String snapshotTemplateId;

    /**
     * 视频点播上传视频
     * 
     * @param request
     * @param user
     * @return
     */
    @MutationField(field = "createUserWorksVideoUpload", description = "创建灵感视频视频点播上传")
    public VideoUploadResult createUserWorksVideoUpload(@NonNull VideoUpload request, ConsumerMemberAuthority user) {
        user.assertLogin();
        return storageService.createVideoUpload(request, VIDEO_SOURCE, VIDEO_LIMIT);
    }

    @MutationField(field = "completeUserWorksVideoUpload", description = "完成灵感视频视频点播上传")
    public StorageInfo completeUserWorksVideoUpload(@NonNull String videoId, ConsumerMemberAuthority user) {
        user.assertLogin();
        return storageService.completeVideoUpload(videoId, VIDEO_SOURCE, info -> {

            // 转码任务
            SubmitJobProcess transcodeJob = new SubmitJobProcess("SubmitTranscodeJobs");
            transcodeJob.getParams().put("templateGroupId", transcodeTemplateGroupId);
            // GIF封面图任务
            SubmitJobProcess gifJob = new SubmitJobProcess("SubmitDynamicImageJob");
            int height = (int) info.getAttributes().get("height");
            int width = (int) info.getAttributes().get("width");
            if (height < width) {
                // 横图
                gifJob.getParams().put("dynamicImageTemplateId", gifHorizontalTemplateId);
            } else {
                // 竖图
                gifJob.getParams().put("dynamicImageTemplateId", gifVerticalityTemplateId);
            }
            // 事件监听
            EventListenerProcess gifListener = new EventListenerProcess("preview", "DynamicImageComplete");
            // 分享
            SubmitJobProcess shareImageJob = new SubmitJobProcess("SubmitSnapshotJob");
            shareImageJob.getParams().put("snapshotTemplateId", snapshotTemplateId);
            EventListenerProcess shareImageListener = new EventListenerProcess("shareImage", "SnapshotComplete");

            storageService.addProcess(info.getStorageId(),
                gifJob,
                gifListener,
                shareImageJob,
                shareImageListener,
                transcodeJob,
                transcodeJob);
        });
    }

    /**
     * 分片上传视频
     * 
     * @param request
     * @param user
     * @return
     */
    @MutationField(field = "createUserWorksVideoMultipartUpload", description = "创建灵感视频分片上传")
    public MultipartUploadResult createUserWorksVideoMultipartUpload(@NonNull MultipartUpload request, ConsumerMemberAuthority user) {
        user.assertLogin();
        return storageService.createMultipartUpload(request, VIDEO_SOURCE, VIDEO_LIMIT);
    }

    @MutationField(field = "completeUserWorksVideoMultipartUpload", description = "完成灵感视频分片上传")
    public StorageInfo completeUserWorksVideoMultipartUpload(@NonNull String uploadId, ConsumerMemberAuthority user) {
        user.assertLogin();
        return storageService.completeMultipartUpload(uploadId, VIDEO_SOURCE, (info) -> {
            // 视频取封面图
            VideoImageProcess videoImageProcess = new VideoImageProcess();
            videoImageProcess.setSync(true);
            videoImageProcess.setFramesNo(5);
            videoImageProcess.setKey("preview");
            videoImageProcess.setFormat("jpg");
            videoImageProcess.setQuality(0.8F);

            // 视频取GIF
            VideoGifProcess videoGifProcess = new VideoGifProcess();
            videoGifProcess.setSync(false);
            videoGifProcess.setKey("preview");
            videoGifProcess.setFormat("gif");
            videoGifProcess.setStartGrabFramesNo(5);
            videoGifProcess.setFramesNumber(40);
            videoGifProcess.setGrabIntervalFrames(30);
            videoGifProcess.setTotalGrabNumber(2);
            videoGifProcess.setQuality(0.8F);

            int height = (int) info.getAttributes().get("height");
            int width = (int) info.getAttributes().get("width");
            if (height < width) {
                videoImageProcess.setZoomMode(ApiConstant.USER_WORKS_COVER_IMAGE_ZOOM_TRANSVERSE);
                videoGifProcess.setZoomMode(ApiConstant.USER_WORKS_COVER_IMAGE_ZOOM_TRANSVERSE);
            } else {
                videoImageProcess.setZoomMode(ApiConstant.USER_WORKS_COVER_IMAGE_ZOOM_VERTICAL);
                videoGifProcess.setZoomMode(ApiConstant.USER_WORKS_COVER_IMAGE_ZOOM_VERTICAL);
            }
            storageService.addProcess(info.getStorageId(), videoImageProcess, videoGifProcess);
        });
    }
}
